/*!
 * \file cicsts_trans.c
 *
 * \brief 交易通信
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.
 *
 * \version 1.0
 * \author songbb
 * \date 2016/04/22
 *
 */

#include <iconv2utf8.h>
#include "conntrack.h"
#include "frct_comm.h"
#include "frreport_comm.h"

#include "cicsts_core.h"
#include "cicsts_comm.h"
#include "cicsts_trans.h"

FR_STATIC int cicsts_mar_get_string(L7_cicsts_packet *p_st_cics_packet
                                    , unsigned int ui_len
                                    , char **pp_out
                                    , unsigned int *p_ui_out_len)
{
    char *p_outtmp = NULL;
    char *p_buff_out = NULL;
    *p_ui_out_len = 0;

    if (ui_len > 0)
    {
        if ((p_outtmp = (char *) frmalloc(ui_len * sizeof(char))) == NULL)
        {
            CICSTS_MALLOCK_ERR;
            goto error;
        }
        if (bytebuff_get_bytes(p_st_cics_packet->p_st_packet, p_outtmp, ui_len) != FR_SUCC)
            goto error;

//        if (p_st_sess->p_encoding != NULL)
//        {
            if (iconv_to_utf8(p_outtmp, ui_len, "gb2312", &p_buff_out, p_ui_out_len) == FR_SUCC)
                goto success;
            cicsts_free((void **) &p_buff_out);
//        }

        if ((p_buff_out = (char *) frmalloc((ui_len + 1) * sizeof(char))) == NULL)
        {
            CICSTS_MALLOCK_ERR;
            goto error;
        }
        memcpy(p_buff_out, p_outtmp, ui_len);
        p_buff_out[ui_len] = '\0';
        *p_ui_out_len = (ui_len + 1) * sizeof(char);
    }

success:
    cicsts_free((void **) &p_outtmp);
    *pp_out = p_buff_out;
    return FR_SUCC;
error:
    cicsts_free((void **) &p_outtmp);
    cicsts_free((void **) &p_buff_out);
    return FR_FAIL;
}

int cicsts_req(Conntrack *p_st_conn
            , L7_cicsts_packet *p_st_cicsts_packet
            , Frhash_header *p_st_hash_report)
{
    CICSTS_PRINT_INFO("cicsts_req...\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_cicsts_private *p_st_session_private = (L7session_cicsts_private *) frct_get_session_private(p_st_session);
    Frhash_header *p_hash_stmt = p_st_session_private->p_hash_stmt;
    char *p_commarea = NULL;
    unsigned int ui_commarea_len = 0;
    L7_cicsts_stmt *p_st_stmt = NULL;
    Frlist_node *p_st_node = NULL;
    Frreport_body_data *p_st_body = NULL;

    if (bytebuff_skip(p_st_cicsts_packet->p_st_packet, p_st_cicsts_packet->ui_header_len) != FR_SUCC)
        goto error;

    // 为确保不重复,先删除
    frhash2_delLong(p_hash_stmt, p_st_cicsts_packet->ui_msg_id, cicsts_stmt_node_free);

    if (cicsts_mar_get_string(p_st_cicsts_packet, (unsigned int) bytebuff_remaining(p_st_cicsts_packet->p_st_packet), &p_commarea, &ui_commarea_len) != FR_SUCC)
        goto error;
    CICSTS_PRINT_ALERT("commarea:[%s]\n", p_commarea);

    if ((p_st_stmt = (L7_cicsts_stmt *) frmalloc(sizeof(L7_cicsts_stmt))) == NULL)
    {
        CICSTS_MALLOCK_ERR;
        goto error;
    }
    memset(p_st_stmt, 0x00, sizeof(L7_cicsts_stmt));
    p_st_stmt->ui_msg_id = p_st_cicsts_packet->ui_msg_id;

    p_st_node = frlist_node_create(p_st_stmt);
    if (frhash2_addLong(p_hash_stmt, p_st_cicsts_packet->ui_msg_id, p_st_node) != FR_SUCC)
        goto error;
    p_st_node = NULL;

    // 新建上报数据结构体
    if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
        goto error;

    if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS_TITLE, "MESSAGE") != FR_SUCC)
        goto error;
    if (frreport_body_l7_add_str(p_st_body, APM_DTS_REPORT_REQ_SERVICE_METHOD, "SEND") != FR_SUCC)
        goto error;
//    if (frreport_body_l7_add_uint(p_st_body, APM_REPORT_KEY_TRANS_RELATED_ID, ui_luw_token) != FR_SUCC)
//        goto error;
    if (p_commarea)
    {
        if (frreport_body_l7_add_uint(p_st_body, APM_DTS_REPORT_REQ_ARG_SIZE, 1) != FR_SUCC)
            goto error;
        if (frreport_body_l7_add_bin(p_st_body, APM_DTS_REPORT_REQ_ARG_DATA, p_commarea, ui_commarea_len) != FR_SUCC)
            goto error;
    }

    // 上报数据
    if (cicsts_report_msg_data_req(p_st_conn, p_st_cicsts_packet, p_st_body, p_st_hash_report, p_st_stmt) != FR_SUCC)
        goto error;

    cicsts_free((void **) &p_commarea);
    return FR_SUCC;
error:
    cicsts_stmt_node_free(p_st_node);
    frhash2_delLong(p_hash_stmt, p_st_cicsts_packet->ui_msg_id, cicsts_stmt_node_free);
    cicsts_free((void **) &p_commarea);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}

int cicsts_resp(Conntrack *p_st_conn
                , L7_cicsts_packet *p_st_cicsts_packet
                , Frhash_header *p_st_hash_report)
{
    CICSTS_PRINT_INFO("cicsts_resp...\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_cicsts_private *p_st_session_private = (L7session_cicsts_private *) frct_get_session_private(p_st_session);
    Frhash_header *p_hash_stmt = p_st_session_private->p_hash_stmt;
    char *p_commarea = NULL;
    unsigned int ui_commarea_len = 0;
    Frreport_body_data *p_st_body = NULL;

    if (bytebuff_skip(p_st_cicsts_packet->p_st_packet, p_st_cicsts_packet->ui_header_len) != FR_SUCC)
        goto error;

    if (cicsts_mar_get_string(p_st_cicsts_packet, (unsigned int) bytebuff_remaining(p_st_cicsts_packet->p_st_packet), &p_commarea, &ui_commarea_len) != FR_SUCC)
        goto error;
    CICSTS_PRINT_ALERT("commarea:[%s]\n", p_commarea);

    // 新建上报数据结构体
    if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
        goto error;

    if (p_commarea)
    {
        if (frreport_body_l7_add_uint(p_st_body, APM_DTS_REPORT_RESP_ARG_SIZE, 1) != FR_SUCC)
            goto error;
        if (frreport_body_l7_add_bin(p_st_body, APM_DTS_REPORT_RESP_ARG_DATA, p_commarea, ui_commarea_len) != FR_SUCC)
            goto error;
    }

    if (frreport_body_l7_add_int(p_st_body, APM_REPORT_KEY_RESP_CODE, 0) != FR_SUCC)
        goto error;

    // 上报数据
    if (cicsts_report_msg_data_resp(p_st_conn, p_st_cicsts_packet, p_st_body, p_st_hash_report) != FR_SUCC)
        goto error;

    frhash2_delLong(p_hash_stmt, p_st_cicsts_packet->ui_msg_id, cicsts_stmt_node_free);
    cicsts_free((void **) &p_commarea);
    return FR_SUCC;
error:
    frhash2_delLong(p_hash_stmt, p_st_cicsts_packet->ui_msg_id, cicsts_stmt_node_free);
    cicsts_free((void **) &p_commarea);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}
